/**
 *  Copyright (C) 2011  Thomas ROBIN
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package triseries;

import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

/**
 * @author tshepo
 * 
 */
public class TreeMenu {

	private static final boolean DEBUG = (Main.debug || MyProperties.debug.equalsIgnoreCase("TreeMenu"));
	private List<TreeMenu> Leafs = new ArrayList<TreeMenu>();
        private String name = null;
        private String url = null;
        private UnwatchEpisode value = null;
        private boolean root = false;

        public TreeMenu() {
        }

        public TreeMenu(String n) {
    		if(DEBUG) System.err.println("TreeMenu.TreeMenu("+n+")");
                name = n;
        }

        public TreeMenu(UnwatchEpisode e) {

    		if(DEBUG) System.err.println("TreeMenu.TreeMenu("+e.GetShow()+e.GetSeason()+e.GetEpisode()+")");
                value = e;
                url = e.GetUrl();
        }

        public TreeMenu(List<UnwatchEpisode> list, String n) {
    		if(DEBUG) System.err.println("TreeMenu.TreeMenu(List,"+n+")");
                if(n == null) {
                	root = true;
                	name = list.get(0).GetShow();
                }
                else name = n;
                url = list.get(0).GetUrl();
                if (list.get(0).SameShow(list).containsAll(list) && !root) {
                        if (list.get(0).SameSeason(list).containsAll(list)) {
                                for (UnwatchEpisode uwe : list) {
                                        Leafs.add(new TreeMenu(uwe));
                                }
                        } else {
                                while (!list.isEmpty()) {
                                        Leafs.add(new TreeMenu(list.get(0).SameSeason(list), "Saison " + list.get(0).GetSeason()));
                                        list.removeAll(list.get(0).SameSeason(list));
                                }
                        }
                } else {
                        while (!list.isEmpty()) {
                                Leafs.add(new TreeMenu(list.get(0).SameShow(list),list.get(0).GetShow()));
                                list.removeAll(list.get(0).SameShow(list));
                        }
                        Optimize();
                }
        }

        public void Optimize() {
    		if(DEBUG) System.err.println("TreeMenu.Optimize()");
        	if (this.nbLeafs() == 0 && this.nbbranch() == 1) {
        		if (!root) 
                	colapse(Leafs.get(0));
        	} 
                List<TreeMenu> Leafs2 = new ArrayList<TreeMenu>();
                Leafs2.addAll(Leafs);
                Leafs.clear();

                for (TreeMenu leaf : Leafs2) {
                        if (leaf.isLeaf()) {
                                Leafs.add(leaf);
                        } else {
                                leaf.Optimize();
                                if (leaf.nbLeafs() < 3 && leaf.nbbranch() == 0 ) {
                                        colapse(leaf);
                                } else {
                                        Leafs.add(leaf);
                                }
                        }
                }
        }

        public boolean isLeaf() {
                return Leafs.isEmpty();
        }

        public int nbLeafs() {
                int i = 0;
                for (TreeMenu tm : Leafs) {
                        if (tm.isLeaf())
                                i++;
                }
                return i;
        }

        public String getName() {
                return name;
        }
        
        public void setName(String n) {
                name = n;
        }

        public int nbbranch() {
                return Leafs.size() - nbLeafs();
        }

        public List<TreeMenu> getLeafs() {
                return Leafs;
        }

        private void colapse(TreeMenu leaf) {
    		if(DEBUG) System.err.println("TreeMenu.colapse("+leaf.name+")");
                Leafs.addAll(leaf.getLeafs());
                Leafs.remove(leaf);
        }

        public void MakeTree(JPopupMenu jpm, int i) {
    		if(DEBUG) System.err.println("TreeMenu.MakeTree(root)");
                for (TreeMenu l : Leafs) {
                        jpm.insert(l.MakeTree(), i++);
                }
        }

        public JMenuItem MakeTree() {
    		if(DEBUG) System.err.println("TreeMenu.MakeTree()");
                if (isLeaf()) {
                        return value.MakeItem();
                } else {
                        JMenu mm = new JMenu(name);
                        for (TreeMenu l : Leafs) {
                                mm.add(l.MakeTree());
                        }
                        return mm;
                }
        }
        
        public boolean removeEp(String url, int saison, int episode) {
    		if(DEBUG) System.err.println("TreeMenu.removeEp("+url+","+saison+","+episode+")");
                if (this.isLeaf()) {
                        if (value.isPreviousOrSameEp(url, saison, episode))
                                return true;
                } else {
                        List<TreeMenu> L = new ArrayList<TreeMenu>();
                        L.addAll(Leafs);
                        for(TreeMenu l : L) {
                                if (l.url.equalsIgnoreCase(url)) {
                                        if(l.removeEp(url, saison, episode))
                                                Leafs.remove(l);
                                        else 
                                                break;
                                }
                        }
                        if (Leafs.isEmpty()) return true;
                }
                return false;
        }

}
